/****************************************************************
 ** Product  :   HP Subscriber Network Application Policy
 ** Module   :   gr-manager
 ** Date: Apr 10, 2015               
 ** Author: Joey Yi
 ** (C) Copyright 2015, Hewlett-Packard Company, All Rights Reserved.
 ** This software is the proprietary information of HP, Inc.  
 ** Use is subject to license terms.
 *****************************************************************
 ** Description:   
 **    FileUtils provide some common methods to operate files/folder. 
 **  
 ****************************************************************/
package com.hp.snap.gr.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;

/**
 * FileUtils provide some common methods to operate files/folder. 
 *
 * <P>
 * Version: 3.3 <br>
 * Author: Joey Yi
 * Date: Apr 10, 2015
 * 
 * </P>
 *
 **/
public class FileUtils {

    private static Logger logger = LoggerFactory.getLogger(FileUtils.class);

    public static boolean deleteFile(File file) {
        if (!file.exists()) {
            return true;
        }
        if (file.isFile()) {
            if (file.delete()) {
                return true;
            }
        } else if (file.isDirectory()) {
            File files[] = file.listFiles();
            if (files != null) {
                for (File fileToDel : files) {
                    if (!deleteFile(fileToDel)) {
                        logger.error("Cannot delete file:" + fileToDel.getAbsolutePath());
                        return false;
                    }
                }
            }
        }
        return file.delete();
    }

    public static boolean copyFile(String fileSrc, String fileDest, boolean isFolder, boolean isForceUpgrade) {
        File srcFile = new File(fileSrc);

        if (!srcFile.exists()) {
            if (!isForceUpgrade) {
                logger.error("The file to copy is not exists: " + fileSrc);
                return false;
            } else {
                logger.info("Force upgrade is enabled, ignore the not existing file: " + fileSrc);
                return true;
            }
        }

        // if the file type is set by in plan, then will check it matched or not
        if (isFolder) {
            if (!srcFile.isDirectory()) {
                logger.info("The file to copy is not a folder which is not matched with patch plan: " + fileSrc);
                return false;
            }
        }

        try {
            copyFolder(srcFile, new File(fileDest));
        } catch (IOException e) {
            logger.info("Copy folder failed from '" + fileSrc + "', to '" + fileDest + "', error: " + e.getMessage());
            return false;
        }

        return true;
    }

    public static void copyFolder(File src, File dest) throws IOException {

        if (src.isDirectory()) {

            //if directory not exists, create it
            if (!dest.exists()) {
                if (dest.mkdir()) {
                    logger.info("Directory copied from " + src + "  to " + dest);
                } else {
                    logger.error("Cannot create the destination folder: " + dest);
                }
            }

            //list all the directory contents
            String files[] = src.list();

            for (String file : files) {
                //construct the src and dest file structure
                File srcFile = new File(src, file);
                File destFile = new File(dest, file);
                //recursive copy
                copyFolder(srcFile, destFile);
            }

        } else {
            //if file, then copy it
            //Use bytes stream to support all file types
            if (!dest.getParentFile().exists()) {
                if (!dest.getParentFile().mkdirs()) {
                    logger.error("Cannot create the destination folder: " + dest.getParentFile());
                }
            }
            InputStream in = null;
            OutputStream out = null;
            try {
                in = new FileInputStream(src);
                out = new FileOutputStream(dest);

                byte[] buffer = new byte[1024];

                int length;
                //copy the file content in bytes
                while ((length = in.read(buffer)) > 0) {
                    out.write(buffer, 0, length);
                }
            } finally {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
            }


            logger.info("File copied from " + src + " to " + dest);
        }
    }

    public static boolean createFolder(String fileName) {
        File file = new File(fileName);
        if (!file.exists() && !file.isDirectory()) {
            return file.mkdirs();
        } else if (file.exists()) {
            return true;
        }
        return false;
    }

    public static boolean createFile(String fileName) {
        try {
            int index = fileName.lastIndexOf(File.separatorChar);
            if (index != -1) {
                String dir = fileName.substring(0, index);
                File file = new File(dir);
                if (!file.exists()) {
                    if (!file.mkdirs()) {
                        return false;
                    }
                } else if (!file.isDirectory()) {
                    if (file.delete() && file.mkdirs()) {
                        return true;
                    }
                    return false;
                }
            }
            File file = new File(fileName);
            if (!file.exists()) {
                if (!file.createNewFile()) {
                    return false;
                }
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    public static boolean writeFile(String content, String filePath) {
        try {
            File dest = new File(filePath);
            if (!dest.getParentFile().exists()) {
                dest.getParentFile().mkdirs();
            }

            InputStream in = null;
            OutputStream out = null;
            try {
                in = new ByteArrayInputStream(content.getBytes());
                out = new FileOutputStream(dest);

                byte[] buffer = new byte[1024];

                int length;
                //copy the file content in bytes
                while ((length = in.read(buffer)) > 0) {
                    out.write(buffer, 0, length);
                }
            } finally {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
            }

        } catch (IOException e) {
            logger.error("Failed to write file: " + filePath);
            return false;
        }
        return true;
    }
}
